#include "core.h"

CApi::CApi(CProduct *ptr)
{
	m_pEcs = ptr;
}

CApi::~CApi()
{
}

void CApi::parseMeta(std::string file)
{
	std::ifstream is;
	is.open (file.c_str(), std::ios::binary); 

	Json::Reader reader;
	Json::Value result;
	if (reader.parse(is, result, false))
	{
		struct SRequest request;
		method = result["isvProtocol"]["method"].asString();
		protocol = result["isvProtocol"]["protocol"].asString();
		name = result["name"].asString();
		int size = result["parameters"]["parameters"].size();
		for (int i=0; i<size; i++)
		{
			request.required = result["parameters"]["parameters"][i]["required"].asString();
			request.tagName = result["parameters"]["parameters"][i]["tagName"].asString();
			request.tagPosition = result["parameters"]["parameters"][i]["tagPosition"].asString();
			request.type = result["parameters"]["parameters"][i]["type"].asString();
			request.bIsSet = false;
			m_mapRequestParameter.insert(std::make_pair(request.tagName, request));
		}
		product = result["product"].asString();
		version = result["version"].asString();

		m_responseMap.itemName.clear();
		m_responseMap.tagName.clear();
		m_responseMap.members.clear();
		m_responseMap.vArraysNode.clear();
		m_responseMap.vStructNode.clear();
		parseMetaResponse(result["resultMapping"], m_responseMap);
	}
	is.close();
}

void CApi::addQuerryParameter(std::string key, std::string value)
{
	std::map<std::string, SRequest>::iterator itdst = m_mapRequestParameter.find(key);
	if (itdst != m_mapRequestParameter.end())
	{
		itdst->second.value = value;
		itdst->second.bIsSet = true;
	}
}

void CApi::getResponseParameter(std::string key, std::string &value)
{

}

std::string CApi::GetQuerryParameter()
{
	std::map<std::string, std::string> mapCommonParameter;
	std::vector<std::string> vecCommonParameter;

	std::map<std::string, SRequest>::iterator it=m_mapRequestParameter.begin();

	mapCommonParameter.insert(std::make_pair("Action", name));
	vecCommonParameter.push_back("Action");
	for (; it!=m_mapRequestParameter.end(); it++)
	{
		if (it->second.bIsSet)
		{
			mapCommonParameter.insert(std::make_pair(it->second.tagName, it->second.value));
			vecCommonParameter.push_back(it->second.tagName);
		}
	}

	add_base_parameter(mapCommonParameter, vecCommonParameter);
 	mapCommonParameter.insert(std::make_pair("Format", m_pEcs->m_retFormat));
 	mapCommonParameter.insert(std::make_pair("Version", version));
 	mapCommonParameter.insert(std::make_pair("AccessKeyId", m_pEcs->m_accessKeyId));
 	mapCommonParameter.insert(std::make_pair("ResourceOwnerAccount", m_pEcs->m_resourceOwnerAccount));

 	vecCommonParameter.push_back("Format");
 	vecCommonParameter.push_back("Version");
 	vecCommonParameter.push_back("AccessKeyId");
 	vecCommonParameter.push_back("ResourceOwnerAccount");

	quicksortHeadersByKey(vecCommonParameter, 0, vecCommonParameter.size()-1);
	
	std::string strQuerryParameter;
	uint32_t count = 0;
	for (std::vector<std::string>::iterator it=vecCommonParameter.begin(); it!=vecCommonParameter.end(); count++, it++)
	{
		strQuerryParameter += urlencode(*it);
		strQuerryParameter += "=";
		strQuerryParameter += urlencode(mapCommonParameter[it->c_str()]);
		
		if (count != vecCommonParameter.size()-1)
		{
			strQuerryParameter += "&";
		}
	}

	std::string StringToSign = m_pEcs->m_method;
	StringToSign += "&";
	StringToSign += urlencode(std::string("/"));
	StringToSign += "&";
	StringToSign += urlencode(strQuerryParameter);
	
	char hamcSha1Out[HMAC_SHA1_OUT_LEN] = {0};
	std::string key = m_pEcs->m_accessKeySecret;
	key += "&";
	hmac_sha1(key.c_str(), key.length(), StringToSign.c_str(), StringToSign.length(), hamcSha1Out);
	std::string signature = base64Encode(hamcSha1Out, HMAC_SHA1_OUT_LEN-1);
	printf("[signature]:%s\n", signature.c_str());

	strQuerryParameter += "&";
	strQuerryParameter += urlencode(std::string("Signature"));
	strQuerryParameter += "=";
	strQuerryParameter += urlencode(signature);

	return strQuerryParameter;
}